分页


只要继承了 APIView 就可以使用分页组件

1.PageNumberPagination 的分页类使用

  • 方式一

    • 视图四部曲中在混合使用方式中使用分页

# views.py

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
from .serializer import *

from rest_framework.pagination import PageNumberPagination


class MyPageNumberPagination(PageNumberPagination):
    page_size = 1  # 每页显示多少条数据
    page_query_param = 'page'  # url的参数名,即: ?page=1
# url 可以通过以下两个参数修改当前页显示多少条数据
    page_size_query_param = 'size'  # url的参数名,即: ?page=1&size=2,如果在url加上该参数就代表临时显示2条数据
    max_page_size = 5  # 设置最大的临时显示数,一般和 page_size_query_param 搭配使用,即: size 所设置的数值不能超过 max_page_size 所设置的数值


class PublishView(APIView):
# 查看所有出版社
    def get(self, request):
        publish_list = Publish.objects.all()

# 分页
        pnp = MyPageNumberPagination()  # 实例化分页对象
        publish_list_page = pnp.paginate_queryset(publish_list, request, self)  # 使用分页对象下的 paginate_queryset 方法处理 queryset 对象(即: 查询到的数据列表)

        ps = PublishSerializers(publish_list_page, many=True)  # 序列化被 paginate_queryset 方法处理后的 queryset 对象(即: 查询到的数据列表)
        return Response(ps.data)

# 接口说明: 查看出版社(带分页)

# 接口: http://127.0.0.1:8000/publish/?page=1

# 请求类型: GET

# 分页说明: 每页显示1条数据

# 结果:

[
    {
        "id": 1,
        "name": "东莞出版社",
        "email": "123@qq.com"
    }
]

# --------------------------------------------------------------

# 接口说明: 查看出版社(带分页)

# 接口: http://127.0.0.1:8000/publish/?page=1&size=3

# 请求类型: GET

# 分页说明: 每页显示1条数据,临时显示3条数据

# 结果:

[
    {
        "id": 1,
        "name": "东莞出版社",
        "email": "123@qq.com"
    },
    {
        "id": 2,
        "name": "广州出版社",
        "email": "123@qq.com"
    },
    {
        "id": 4,
        "name": "深圳出版社",
        "email": "123@qq.com"
    }
]

  • 方式二

    • 视图四部曲中除了混合使用方式外的其他方式使用分页

    • pagination_class = 分页类

# views.py

from .models import *
from .serializer import *
from rest_framework import viewsets

from rest_framework.pagination import PageNumberPagination


class MyPageNumberPagination(PageNumberPagination):
    page_size = 1  # 每页显示多少条数据
    page_query_param = 'page'  # url的参数名,即: ?page=1
# url 可以通过以下两个参数修改当前页显示多少条数据
    page_size_query_param = 'size'  # url的参数名,即: ?page=1&size=2,如果在url加上该参数就代表临时显示2条数据
    max_page_size = 5  # 设置最大的临时显示数,一般和 page_size_query_param 搭配使用,即: size 所设置的数值不能超过 max_page_size 所设置的数值


class PublishViewSet(viewsets.ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializers

pagination_class = MyPageNumberPagination

# 接口说明: 查看出版社(带分页)

# 接口: http://127.0.0.1:8000/publish/?page=1

# 请求类型: GET

# 分页说明: 每页显示1条数据

# 结果:

{
    "count": 11,  # 总页数
    "next": "http://127.0.0.1:8000/publish/?page=2",  # 下一页的网址,没有则为 null
    "previous": null,  # 上一页的网址,没有则为 null
    "results": [
        {
            "id": 1,
            "name": "东莞出版社",
            "email": "123@qq.com"
        }
    ]
}

# --------------------------------------------------------------

# 接口说明: 查看出版社(带分页)

# 接口: http://127.0.0.1:8000/publish/?page=1&size=3

# 请求类型: GET

# 分页说明: 每页显示1条数据,临时显示3条数据

# 结果:

{
    "count": 11,  # 总页数
    "next": "http://127.0.0.1:8000/publish/?page=2&size=3",  # 下一页的网址,没有则为 null
    "previous": null,  # 上一页的网址,没有则为 null
    "results": [
        {
            "id": 1,
            "name": "东莞出版社",
            "email": "123@qq.com"
        },
        {
            "id": 2,
            "name": "广州出版社",
            "email": "123@qq.com"
        },
        {
            "id": 4,
            "name": "深圳出版社",
            "email": "123@qq.com"
        }
    ]
}

  • 配置全局的分页参数 -> 不建议使用

    • 如果配置了全局的分页参数可以不用创建分页类,直接使用 PageNumberPagination 分页类

    • 只有 PAGE_SIZE 这个参数可以进行设置

# settings.py

REST_FRAMEWORK = {
# "DEFAULT_AUTHENTICATION_CLASSES": ["app01.rf_auth.TokenAuth"],  # 全局认证
    # "DEFAULT_PERMISSION_CLASSES": ["app01.rf_permission.SVIPPermission"]  # 全局权限
    # 'DEFAULT_PARSER_CLASSES': ['rest_framework.parsers.JSONParser']  # 全局解析器
    'PAGE_SIZE': 1,  # 分页 -> 一页显示多少条数据
}

# views.py

# 方式一

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
from .serializer import *

from rest_framework.pagination import PageNumberPagination


class PublishView(APIView):
 # 查看所有出版社
    def get(self, request):
        publish_list = Publish.objects.all()

# 分页
        pnp = PageNumberPagination()  # 实例化分页对象
        publish_list_page = pnp.paginate_queryset(publish_list, request, self)  # 使用分页对象下的 paginate_queryset 方法处理 queryset 对象(即: 查询到的数据列表)

        ps = PublishSerializers(publish_list_page, many=True)  # 序列化被 paginate_queryset 方法处理后的 queryset 对象(即: 查询到的数据列表)
        return Response(ps.data)

# -----------------------------------------

# 方式二

from .models import *
from .serializer import *
from rest_framework import viewsets

from rest_framework.pagination import PageNumberPagination


class PublishViewSet(viewsets.ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializers

pagination_class = PageNumberPagination

2.LimitOffsetPagination 的偏移分页类使用

  • LimitOffsetPagination的使用方式和PageNumberPagination的使用方式是一样,只是LimitOffsetPagination分页类的参数和功能不一样而已

  • 方式一

    • 视图四部曲中在混合使用方式中使用分页

# views.py

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
from .serializer import *

from rest_framework.pagination import LimitOffsetPagination


class MyLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 2  # 显示多少条数据
    limit_query_param = 'limit'  # url的参数名,即: ?limit=2
    offset_query_param = 'offset'  # url的参数名,即: ?limit=2&offset=1,如果在url加上该参数就代表从1开始偏移几位
    max_limit = 5  # 限制最多显示多少条数据


class PublishView(APIView):
# 查看所有出版社
    def get(self, request):
        publish_list = Publish.objects.all()

# 分页
        lop = MyLimitOffsetPagination()  # 实例化分页对象
        publish_list_page = lop.paginate_queryset(publish_list, request, self)  # 使用分页对象下的 paginate_queryset 方法处理 queryset 对象(即: 查询到的数据列表)

        ps = PublishSerializers(publish_list_page, many=True)  # 序列化被 paginate_queryset 方法处理后的 queryset 对象(即: 查询到的数据列表)
        return Response(ps.data)

# 接口说明: 查看出版社(带分页)

# 接口: http://127.0.0.1:8000/publish/?offset=2

# 请求类型: GET

# 分页说明: 显示2条数据,从1开始偏移2条数据

# 结果:

[
    {
        "id": 3,
        "name": "深圳出版社",
        "email": "123@qq.com"
    },
    {
        "id": 4,
        "name": "深圳出版社",
        "email": "123@qq.com"
    }
]

# --------------------------------------------------------------

# 接口说明: 查看出版社(带分页)

# 接口: http://127.0.0.1:8000/publish/?limit=3&offset=2

# 请求类型: GET

# 分页说明: 显示3条数据,从1开始偏移2条数据

# 结果:

[
    {
        "id": 3,
        "name": "深圳出版社",
        "email": "123@qq.com"
    },
    {
        "id": 4,
        "name": "深圳出版社",
        "email": "123@qq.com"
    },
    {
        "id": 5,
        "name": "深圳出版社",
        "email": "123@qq.com"
    }
]

  • 方式二

    • 视图四部曲中除了混合使用方式外的其他方式使用分页

    • pagination_class = 分页类

# views.py

from .models import *
from .serializer import *
from rest_framework import viewsets

from rest_framework.pagination import LimitOffsetPagination


class MyLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 2  # 显示多少条数据
    limit_query_param = 'limit'  # url的参数名,即: ?limit=2
    offset_query_param = 'offset'  # url的参数名,即: ?limit=2&offset=1,如果在url加上该参数就代表从1开始偏移几位
    max_limit = 5  # 限制最多显示多少条数据


class PublishViewSet(viewsets.ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializers

pagination_class = MyLimitOffsetPagination

# 接口说明: 查看出版社(带分页)

# 接口: http://127.0.0.1:8000/publish/?offset=1

# 请求类型: GET

# 分页说明: 默认显示2条数据,从1开始偏移1条数据

# 结果:

{
    "count": 11,  # 总页数
    "next": "http://127.0.0.1:8000/publish/?limit=2&offset=3",  # 下一页的网址,没有则显示null
    "previous": "http://127.0.0.1:8000/publish/?limit=2",  # 上一页的网址,没有则显示null
    "results": [
        {
            "id": 2,
            "name": "广州出版社",
            "email": "123@qq.com"
        },
        {
            "id": 4,
            "name": "深圳出版社",
            "email": "123@qq.com"
        }
    ]
}

# --------------------------------------------------------------

# 接口说明: 查看出版社(带分页)

# 接口: http://127.0.0.1:8000/publish/?limit=3&offset=2

# 请求类型: GET

# 分页说明: 显示3条数据,从1开始偏移2条数据

# 结果:

{
    "count": 11,  # 总页数
    "next": "http://127.0.0.1:8000/publish/?limit=3&offset=5",  # 下一页的网址,没有则显示null
    "previous": "http://127.0.0.1:8000/publish/?limit=3",  # 上一页的网址,没有则显示null
    "results": [
        {
            "id": 4,
            "name": "深圳出版社",
            "email": "123@qq.com"
        },
        {
            "id": 5,
            "name": "深圳出版社",
            "email": "123@qq.com"
        },
        {
            "id": 6,
            "name": "深圳出版社",
            "email": "123@qq.com"
        }
    ]
}

  • 配置全局的分页参数 -> 不建议使用

    • 如果配置了全局的分页参数可以不用创建分页类,直接使用 LimitOffsetPagination 分页类

    • 只有 PAGE_SIZE 这个参数可以进行设置

    • 这里的 PAGE_SIZE 参数指的是 default_limit 参数

# settings.py

REST_FRAMEWORK = {
# "DEFAULT_AUTHENTICATION_CLASSES": ["app01.rf_auth.TokenAuth"],  # 全局认证
    # "DEFAULT_PERMISSION_CLASSES": ["app01.rf_permission.SVIPPermission"]  # 全局权限
    # 'DEFAULT_PARSER_CLASSES': ['rest_framework.parsers.JSONParser']  # 全局解析器
    'PAGE_SIZE': 2,  # 分页 -> 显示多少条数据
}

# views.py

# 方式一

from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
from .serializer import *

from rest_framework.pagination import LimitOffsetPagination


class PublishView(APIView):
 # 查看所有出版社
    def get(self, request):
        publish_list = Publish.objects.all()

# 分页
        lop = LimitOffsetPagination()  # 实例化分页对象
        publish_list_page = lop.paginate_queryset(publish_list, request, self)  # 使用分页对象下的 paginate_queryset 方法处理 queryset 对象(即: 查询到的数据列表)

        ps = PublishSerializers(publish_list_page, many=True)  # 序列化被 paginate_queryset 方法处理后的 queryset 对象(即: 查询到的数据列表)
        return Response(ps.data)

# -------------------------------------------

# 方式二

from .models import *
from .serializer import *
from rest_framework import viewsets

from rest_framework.pagination import LimitOffsetPagination


class PublishViewSet(viewsets.ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializers

    pagination_class = LimitOffsetPagination